package cz.muni.fi.pa036is.controllers;

import cz.muni.fi.pa036is.dto.AddressTO;
import cz.muni.fi.pa036is.dto.AdmissionGridTO;
import cz.muni.fi.pa036is.dto.LoginDTO;
import cz.muni.fi.pa036is.dto.PersonDetailTO;
import cz.muni.fi.pa036is.dto.PersonFormTO;
import cz.muni.fi.pa036is.dto.SeasonDetailTO;
import cz.muni.fi.pa036is.servicesinterface.AddressService;
import cz.muni.fi.pa036is.servicesinterface.AdmissionService;
import cz.muni.fi.pa036is.servicesinterface.PersonService;
import cz.muni.fi.pa036is.servicesinterface.SeasonService;
import cz.muni.fi.pa036is.utilities.DateEditor;
import cz.muni.fi.pa036is.validators.AddressValidator;
import cz.muni.fi.pa036is.validators.PersonValidator;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
@SessionAttributes(value = {"person", "comment"})
public class PersonController {

	@Autowired
	private PersonService personService;
	@Autowired
	private AddressService addressService;
	@Autowired
	private AdmissionService admissionService;
	@Autowired
	private SeasonService seasonService;

        @InitBinder
        public void initBinder(WebDataBinder binder) {
            binder.registerCustomEditor(Date.class, new DateEditor());
        }
        
	// List
	@RequestMapping("/admin/person/person")
	public String seasons(ModelMap model) {

		model.addAttribute("persons", this.personService.getAllPersonsForDropDown());
		model.addAttribute("login", new LoginDTO());
		return "/admin/person/person";
	}

	// Detail
	@RequestMapping(value = "/admin/person/detail", params = "id")
	public String detail(@RequestParam("id") Long id, ModelMap model) {
		PersonDetailTO person = this.personService.getPersonDetail(id);

		List<AdmissionGridTO> admissions = this.admissionService.getAdmissionsForPerson(person);
		List<SeasonDetailTO> seasons = this.seasonService.getSeasonsByPerson(person);

		if (person.getAddress() == null) {
			person.setAddress(this.addressService.getAddressByPerson(id));
		}

		model.addAttribute("login", new LoginDTO());
		model.addAttribute("person", person);
		model.addAttribute("admissions", admissions);
		model.addAttribute("seasons", seasons);

		return "/admin/person/detail";
	}

	// Edit
	@RequestMapping(value = "/admin/person/edit", params = "id")
	public String edit(@RequestParam("id") Long id, ModelMap model) {


		PersonFormTO person = null;
		if (id == null || id < 0) {
			person = new PersonFormTO();
			person.setAddress(new AddressTO());
		} else {
			person = this.personService.getPersonForm(id);
		}

		model.addAttribute("person", person);

		return "/admin/person/edit";
	}

	@RequestMapping(value = "/admin/person/edit", method = RequestMethod.POST)
	public String edit(@Validated @ModelAttribute("person") PersonFormTO person, BindingResult result, ModelMap model,
			HttpSession session) {

             PersonValidator personValidator = new PersonValidator();
             personValidator.validate(person, result);
             
             AddressValidator addressValidator = new AddressValidator();
             addressValidator.validate(person.getAddress(), result);
       
		if (result.hasErrors()) {
                    
                    HashMap<String, String> errors = new HashMap<String, String>();
                    for (FieldError error : result.getFieldErrors()) {
                        errors.put(error.getField(), error.getDefaultMessage());
                    }
			model.put("person", person);
			return "/admin/person/edit";
		}

		if (person.getId() != null && person.getId() >= 0) {
			this.personService.editPerson(person);
		} else {
			this.personService.addPerson(person);
		}

		return "redirect:/admin/person/detail?id=" + person.getId();
	}

	@RequestMapping(value = "/admin/person/remove", params = "id")
	public String remove(@RequestParam("id") Long id, ModelMap model, HttpSession session) {

		personService.deletePerson(id);
		return "redirect:/admin/person/person";
	}
}
